//
//  UIView+Extension.swift
//  DaDainan
//
//  Created by 刘泽 on 2017/11/11.
//  Copyright © 2017年 唐山徕思歌科技有限公司. All rights reserved.
//

import Foundation
import UIKit

@IBDesignable
extension UIView {


    //MARK:Viwe设置圆角
    @IBInspectable public var cornerRadius: CGFloat {
        get {
            return layer.cornerRadius
        }
        // also  set(newValue)
        set {
            layer.cornerRadius = newValue
            if self.isKind(of: UIImageView.self) {
                layer.masksToBounds = true
            }
            let color = backgroundColor
            backgroundColor = UIColor.clear
            layer.backgroundColor = color?.cgColor

        }
    }

    //MARK:Viwe设置border 宽度
    @IBInspectable public var borderWidth : CGFloat {
        get {
            return layer.borderWidth
        }
        // also  set(newValue)
        set {
            layer.borderWidth = newValue
        }
    }

    //MARK:Viwe设置border 宽度
    @IBInspectable public var borderColor : UIColor {
        get {
            return UIColor(cgColor: layer.borderColor!)

        }
        // also  set(newValue)
        set {
            layer.borderColor = newValue.cgColor
        }
    }

    //MARK:阴影颜色
    @IBInspectable public var shadowColor : UIColor{
        get{
            return UIColor.init(cgColor: layer.shadowColor!)
        }
        set{
            layer.shadowColor = newValue.cgColor
        }
    }

    //MARK:阴影偏移
    @IBInspectable public var shadowSize : CGSize{
        get{
            return layer.shadowOffset
        }
        set{
            layer.shadowOffset = newValue
        }
    }

    //MARK:阴影透明度
    @IBInspectable public var shadowAlpha : Float{
        get{
            return layer.shadowOpacity
        }
        set{
            layer.shadowOpacity = newValue
        }
    }

    //MARK:阴影半径
    @IBInspectable public var shadowRadius : CGFloat{
        get{
            return layer.shadowRadius
        }
        set{
            layer.shadowRadius = newValue
        }
    }

    //MARK:所在的viewController
    public var viewController : UIViewController?{
        get{
            for view in sequence(first: self.superview, next: {$0?.superview}){
                if let responder = view?.next{
                    if responder.isKind(of: UIViewController.self){
                        return responder as? UIViewController
                    }
                }
            }
            return nil
        }
    }

    //MARK:添加圆角
    public func addCorner(roundingCorners: UIRectCorner, cornerSize: CGSize) {
        let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: roundingCorners, cornerRadii: cornerSize)
        let cornerLayer = CAShapeLayer()
        cornerLayer.frame = bounds
        cornerLayer.path = path.cgPath

        layer.mask = cornerLayer
    }

    //MARK:设置默认阴影效果
    public func setDefaultShadow()  {
        self.layer.shadowOpacity = 0.8
        self.layer.shadowColor = UIColor.lightGray.cgColor
        self.layer.shadowOffset = CGSize(width: 1, height: 1)
        self.layer.shadowRadius = 5
        self.layer.masksToBounds = false
    }

    //MARK:设置阴影效果
    public func addShadow(color: UIColor, offset: CGSize, alpha: Float, radius: CGFloat){
        self.layer.shadowOpacity = alpha
        self.layer.shadowColor = color.cgColor
        self.layer.shadowOffset = offset
        self.layer.shadowRadius = radius
        self.layer.masksToBounds = false
        self.layer.shouldRasterize = true
        self.layer.rasterizationScale = UIScreen.main.scale
    }

    //MARK:隐藏上下不占位置
    public func hiddenUpDown(){
        self.isHidden = true

        for item in constraints{
            if item.firstAttribute == .height{
                item.constant = 0
                return
            }
        }
        let heightLayout = NSLayoutConstraint.init(item: self, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 1, constant: 0)
        addConstraint(heightLayout)
    }

    //MARK:隐藏左右不占位置
    public func hiddenLeftRight(){
        self.isHidden = true
        for item in constraints{
            if item.firstAttribute == .width{
                item.constant = 0
            }
        }
        let widthLayout = NSLayoutConstraint.init(item: self, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .width, multiplier: 1, constant: 0)
        addConstraint(widthLayout)
    }


    //MARK:设置圆形进度条
    ///要加在superView上
    /// - Parameters:
    ///   - centerPoind: 中心点
    ///   - radius: 圆角
    ///   - progress: 进度比例
    ///   - progressColor: 进度条颜色
    ///   - residueColor: 背景颜色
    ///   - lineWidth: 进度条宽度
    ///   - animat: 是否有动画
    ///   - duration: 动画时间
    ///   - frome: 开始进度
    ///   - to: 结束进度
    public func addCornerProgress(centerPoind:CGPoint,radius:CGFloat,progress:CGFloat,progressColor:UIColor = UIColor.init(red: 102/255, green: 165/255, blue: 92/255, alpha: 1),residueColor:UIColor = UIColor.init(red: 217/255, green: 153/255, blue: 34/255, alpha: 1),lineWidth:CGFloat = 15,animat:Bool = true,frome:Double=0,to:Double=1,duration:Double = 1.0){
        let path1 = UIBezierPath.init(arcCenter: centerPoind, radius: radius, startAngle: 0, endAngle: CGFloat(2 * Double.pi), clockwise: true)
        let path2 = UIBezierPath.init(arcCenter: centerPoind, radius: radius, startAngle: CGFloat(-0.5 * Double.pi), endAngle:  CGFloat(1.5 * Double.pi) * progress, clockwise: true)
        let layer = CAShapeLayer()
        layer.path = path1.cgPath
        layer.lineWidth = lineWidth
        layer.fillColor = UIColor.clear.cgColor
        layer.strokeColor = progressColor.cgColor
        layer.lineCap = kCALineCapRound
        self.layer.addSublayer(layer)
        let layer1 = CAShapeLayer()
        layer1.path = path2.cgPath
        layer1.lineWidth = lineWidth
        layer1.fillColor = UIColor.clear.cgColor
        layer1.strokeColor = residueColor.cgColor
        self.layer.addSublayer(layer1)
        if animat{
            DispatchQueue.global().async {
                layer1.animation1(from: frome, to: to, duration: duration)
            }
        }
    }

    //MARK:画圆圈
    public func addCircle(centerPoind:CGPoint,radius:CGFloat,color:UIColor,lineWidth:CGFloat = 1){
        let path1 = UIBezierPath.init(arcCenter: centerPoind, radius: radius, startAngle: 0, endAngle: CGFloat(2 * Double.pi), clockwise: true)
        let layer = CAShapeLayer()
        layer.path = path1.cgPath
        layer.lineWidth = lineWidth
        layer.fillColor = UIColor.clear.cgColor
        layer.strokeColor = color.cgColor
        self.layer.addSublayer(layer)
    }


    public var width: CGFloat {
        get { return self.frame.size.width }
        set {
            var frame = self.frame
            frame.size.width = newValue
            self.frame = frame
        }
    }

    public var height: CGFloat {
        get { return self.frame.size.height }
        set {
            var frame = self.frame
            frame.size.height = newValue
            self.frame = frame
        }
    }

    public var size: CGSize  {
        get { return self.frame.size }
        set {
            var frame = self.frame
            frame.size = newValue
            self.frame = frame
        }
    }

    public var origin: CGPoint {
        get { return self.frame.origin }
        set {
            var frame = self.frame
            frame.origin = newValue
            self.frame = frame
        }
    }

    public var x: CGFloat {
        get { return self.frame.origin.x }
        set {
            var frame = self.frame
            frame.origin.x = newValue
            self.frame = frame
        }
    }
    public var y: CGFloat {
        get { return self.frame.origin.y }
        set {
            var frame = self.frame
            frame.origin.y = newValue
            self.frame = frame
        }
    }

    public var centerX: CGFloat {
        get { return self.center.x }
        set {
            self.center = CGPoint(x: newValue, y: self.center.y)
        }
    }

    public var centerY: CGFloat {
        get { return self.center.y }
        set {
            self.center = CGPoint(x: self.center.x, y: newValue)
        }
    }

    public var top : CGFloat {
        get { return self.frame.origin.y }
        set {
            var frame = self.frame
            frame.origin.y = newValue
            self.frame = frame
        }
    }

    public var bottom : CGFloat {
        get { return frame.origin.y + frame.size.height }
        set {
            var frame = self.frame
            frame.origin.y = newValue - self.frame.size.height
            self.frame = frame
        }
    }

    public var right : CGFloat {
        get { return self.frame.origin.x + self.frame.size.width }
        set {
            var frame = self.frame
            frame.origin.x = newValue - self.frame.size.width
            self.frame = frame
        }
    }

    public var left : CGFloat {
        get { return self.frame.origin.x }
        set {
            var frame = self.frame
            frame.origin.x  = newValue
            self.frame = frame
        }
    }




    /**
     Init from nib
     Notice: The nib file name is the same as the calss name

     - returns: UINib
     */
    class public func nib() -> UINib {
        let hasNib: Bool = Bundle.main.path(forResource: self.className, ofType: "nib") != nil
        guard hasNib else {
            assert(!hasNib, "Nib is not exist")
            return UINib()
        }
        return UINib(nibName: self.className, bundle:nil)
    }

    /**
     Init from nib and get the view
     Notice: The nib file name is the same as the calss name

     Demo： UIView.ts_viewFromNib(TSCustomView)

     - parameter aClass: your class

     - returns: Your class's view
     */
    class public func viewFromNib<T>(_ aClass: T.Type) -> T {
        let name = String(describing: aClass)
        if Bundle.main.path(forResource: name, ofType: "nib") != nil {
            return UINib(nibName: name, bundle:nil).instantiate(withOwner: nil, options: nil)[0] as! T
        } else {
            fatalError("\(String(describing: aClass)) nib is not exist")
        }
    }

    /**
     All subviews of the UIView
     - returns: A group of UIView
     */
    public func ts_allSubviews() -> [UIView] {
        var stack = [self]
        var views = [UIView]()
        while !stack.isEmpty {
            let subviews = stack[0].subviews as [UIView]
            views += subviews
            stack += subviews
            stack.remove(at: 0)
        }
        return views
    }

    /**
     Take snap shot

     - returns: UIImage
     */
    public func ts_takeSnapshot() -> UIImage {
        UIGraphicsBeginImageContextWithOptions(bounds.size, false, UIScreen.main.scale)
        drawHierarchy(in: self.bounds, afterScreenUpdates: true)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image!
    }

    /// Check the view is visible
    @available(iOS 8.0, *)
    public var isVisible: Bool {
        get {
            if self.window == nil || self.isHidden || self.alpha == 0 {
                return false
            }

            let viewRect = self.convert(self.bounds, to: nil)


            return viewRect.intersects(window!.bounds) == false
        }
    }

    //MARK:添加点击事件
    public func addTap(target:Any?,action:Selector?){
        let  tap = UITapGestureRecognizer(target: target, action: action)
        isUserInteractionEnabled = true
        self.addGestureRecognizer(tap)
    }

    //MARK:添加渐变色背景
    public func addGradientBg(from: UIColor, to: UIColor ,isHorizontal : Bool = false){
        var isHave = false
        if let sublayers = layer.sublayers{
            for item in sublayers{
                if item.isKind(of: CAGradientLayer.self){
                    isHave = true
                    break
                }
            }
        }
        if !isHave {
            let gradientColors = [from.cgColor,to.cgColor]
            let locations : [NSNumber] = [0.0,1.0]
            //创建CAGradientLayer对象并设置参数
            let gradientLayer = CAGradientLayer()
            gradientLayer.colors = gradientColors
            gradientLayer.locations = locations
            if isHorizontal{
                gradientLayer.startPoint = CGPoint(x: 0, y: 0.5)
                gradientLayer.endPoint = CGPoint(x: 1, y: 0.5)
            }

            //设置其CAGradientLayer对象的frame，并插入view的layer
            gradientLayer.frame = bounds
            gradientLayer.cornerRadius = layer.cornerRadius
            layer.insertSublayer(gradientLayer, at: 0)
        }

    }

    //MARK:获取view截图
    public func shotImage() -> UIImage{
        let size = bounds.size
        UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale)
        drawHierarchy(in: bounds, afterScreenUpdates: true)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        if image == nil{
            print("截图是空")
        }
        return image ?? UIImage()
    }

    //MARK:添加呼吸灯效果
    public func addBreatheLight(_ duration:CFTimeInterval = 2){
        let opacityA = CABasicAnimation(keyPath: "opacity")
        opacityA.fromValue = 1
        opacityA.toValue = 0.3
        opacityA.duration = duration
        opacityA.repeatCount = 99999
        opacityA.autoreverses = true
        opacityA.isRemovedOnCompletion = false
        opacityA.fillMode = kCAFillModeForwards
        opacityA.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)
        self.layer.add(opacityA, forKey: "aAlpha")

    }
    //MARK:移除呼吸灯效果
    public func removeBreatheLight(){
        self.layer.removeAnimation(forKey: "aAlpha")
    }
}

extension CAShapeLayer{
    public func animation1(from:Double=0,to:Double=1,duration:Double) {
        let animation = CABasicAnimation(keyPath: "strokeEnd")
        animation.fromValue = from
        animation.toValue = to
        animation.duration = duration
        self.add(animation, forKey: "")
    }

}

//MARK:给view加indexPath在tableView 里代替tag的使用
extension UIView{

     fileprivate struct AssociatedKey{
          static var indexPath : IndexPath = IndexPath(item: 0, section: 0)
     }

     public var ss_indexPath : IndexPath{
          get{
               let indexPath = objc_getAssociatedObject(self, &AssociatedKey.indexPath) as? IndexPath
               return indexPath ?? IndexPath(item: 0, section: 0)
          }

          set{
               objc_setAssociatedObject(self, &AssociatedKey.indexPath, newValue, .OBJC_ASSOCIATION_RETAIN)
          }
     }

}
